<template>
  <el-upload class="upload-file" drag :action="$common.fileUrl + param.upload" :show-file-list="false"
    :on-success="handleAvatarSuccess" :before-upload="handleBeforeUpload" :on-error="handleAvatarError"
    :on-change="onChange" :http-request="handleRequest" :disabled="param.disabled">
    <div v-if="error">
      <div style="width: 160px; margin: 0 auto;">
        <el-progress :percentage="progressPercent" status="exception" :text-inside="true" :stroke-width="6"
          :show-text="false"></el-progress>
      </div>
      <div style="margin-top: 16px"><span class="error_span">上传失败</span> &nbsp; <span class="reload_upload">重试</span>
      </div>
    </div>
    <div v-else>
      <div v-if="file" class="show_file">
        <el-image :src="fileIcon" style="width: 60px" @click.stop="openFile"></el-image>
        <el-icon class="delete_icon" size="20" @click.stop="deleteFile"><CircleCloseFilled /></el-icon>
        <div class="upload_icon_title">
          <span>{{ param.title }}.{{ file.split('.')[file.split('.').length-1] }}</span>
        </div>
        <div class="upload__text">
          文件上传完成
        </div>
      </div>
      <div v-else>
        <div class="upload_icon_title">
          <div style="width: 160px" v-if="progressPercent != 0">
            <el-progress :percentage="progressPercent" :text-inside="true" :stroke-width="6"
              :show-text="false"></el-progress>
            <br />
            <div class="upload_in">上传中（{{progressPercent}}%）</div>
          </div>
          <div v-else class="icon_box">
            <el-icon size="20" color="#56a032"><upload-filled /></el-icon>
            <span v-if="file">{{ param.title }}.{{ file.split('.')[file.split('.').length-1] }}</span>
            <span v-else>添加文件</span>
          </div>
        </div>
        <div v-if="!file && progressPercent == 0" class="upload__text">
          <!-- {{ param.isPDF ? '只能上传pdf文件!' : '' }}{{ param.isPDFandPIC ? '上传的文件只能是pdf、jpg、png、jpeg格式!' : '' }}<br />
              大小不超过{{param.fileSize}}M -->
          点击或拖拽上传
        </div>
      </div>
    </div>
  </el-upload>
</template>
  
<script lang="ts" setup>
import { UploadFilled, CircleCloseFilled } from '@element-plus/icons-vue'
import { ref, reactive, watch, computed, inject, defineAsyncComponent, defineEmits, onMounted } from "vue";
const $axios: any = inject('$axios')
const $common: any = inject('$common')
const $utils: any = inject('$utils')
const $MessageBox: any = inject('$MessageBox')
const emits = defineEmits(['cancel', 'ok', 'buttons-ready', 'change'])
import fileIcon from '@/assets/icon/file.png';

/** 下载文件 */
const downloadFile = (pathToken: any) => {
  if (pathToken) {
    $utils
      .downloadImageOss({ filePath: pathToken })
      .then((result: any) => {
        filePath.value = result.fileUrl;
      })
      .catch((error: any) => {
        $MessageBox.alert({ txt: "影像获取错误！", type: 'danger' }).then(() => { }).catch(() => { })
      });
  }
}

const progressPercent = ref(0);
const file = ref('');
const error = ref(false);
const filePath = ref('');
interface Props {
  title?: string;
  value?: string | null;
  fileSize?: number;
  disabled?: boolean;
  isPDF?: boolean;
  isPDFandPIC?: boolean;
  lookUrl?: string;
  isRelationNo?: string | null;
  upload?: string;
  params?: any;
}
const props = withDefaults(defineProps<Props>(), {
  title: '上传文件',//标题
  value: null,
  fileSize: 10,//限制大小
  disabled: false,//是否禁用
  isPDF: false,//是否只能上传pdf
  isPDFandPIC: false,//是否只能上传pdf和图片
  lookUrl: '',//预览比较值
  isRelationNo: null,//商户入网的图片一个商户在同一个路径下
  upload: 'upload?path=/merchant/mcht',
  params: null,
});
interface Param {
  [key: string]: any; // 添加索引签名
  value: string | null;
  upload: string;
  fileSize: number;
  title: string;
  disabled: boolean;
  isPDF: boolean;
  isPDFandPIC: boolean;
  lookUrl: string;
  isRelationNo: string | null;
}
const param: Param = reactive({
  value: props.value,
  upload: props.upload,
  fileSize: props.fileSize,
  title: props.title,
  disabled: props.disabled,
  isPDF: props.isPDF,
  isPDFandPIC: props.isPDFandPIC,
  lookUrl: props.lookUrl,
  isRelationNo: props.isRelationNo,
});
watch(
  () => props.params,
  (newValue) => {
    if (newValue) {
      Object.keys(param).forEach(key => {
        if (param.hasOwnProperty(key)) {
          (param as Record<string, any>)[key] = (newValue as Record<string, any>)[key];
        }
      });
    }
  },
  { immediate: true }
);
watch(
  () => props.value,
  (newValue) => {
    file.value = newValue || '';
    if (newValue) {
      downloadFile(newValue);
    }
  },
  { immediate: true, deep: true },
);
watch(
  () => param.value,
  (newValue) => {
    file.value = newValue || '';
    if (newValue) {
      downloadFile(newValue);
    }
  },
  { immediate: true, deep: true },
);
watch(
  file,
  (newValue, oldValue) => {
    emits('change', { file });
  },
  { deep: true }
);

/** 删除文件 */
const deleteFile = () => {
  file.value = '';
  progressPercent.value = 0;
}
/** 打开文件 */
const openFile = () => {
  window.open(filePath.value, '_blank')
}
/** 文件上传之前判断文件的大小 */
const handleBeforeUpload = (file: any) => {
  if (param.isPDF) {
    const isPDFType = file.type === "application/pdf";
    if (!isPDFType) {
      $MessageBox.alert({ txt: '只能上传pdf文件!', type: 'danger' }).then(() => { }).catch(() => { })
    }
    return isPDFType;
  }
  if (param.isPDFandPIC) {
    const types = ["image/jpeg", "image/jpg", "image/png", "application/pdf"];
    const isImage = types.includes(file.type);
    if (!isImage) {
      $MessageBox.alert({ txt: '上传的文件只能是pdf、jpg、png、jpeg格式!', type: 'danger' }).then(() => { }).catch(() => { })
      return false;
    }
  }
  const { size } = file;
  const isUoload = (size / 1024 / 1024) <= Number(param.fileSize);
  if (!isUoload) {
    $MessageBox.alert({ txt: `上传的文件不能大于${param.fileSize}M!`, type: 'danger' }).then(() => { }).catch(() => { })
    return false;
  }
  if (file.size == 0) {
    $MessageBox.alert({ txt: '上传的文件不能为空！', type: 'danger' }).then(() => { }).catch(() => { })
  }
};
/** 数据更改 */
const onChange = (file: any, fileList: any) => {
  // 数据小于0.1M的时候按KB显示
  const size = file.size / 1024 / 1024 > 0.1 ? `(${(file.size / 1024 / 1024).toFixed(1)}M)` : `(${(file.size / 1024).toFixed(1)}KB)`;
  file.name.indexOf("M") > -1 || file.name.indexOf("KB") > -1 ? file.name : (file.name += size);
};
/** 上传请求 */
const handleRequest = (data: any) => {
  const formdata = new FormData();
  formdata.append("file", data.file);
  const config = {
    onUploadProgress: (progressEvent: any) => {
      // progressEvent.loaded:已上传文件大小
      // progressEvent.total:被上传文件的总大小
      progressPercent.value = Number(((progressEvent.loaded / progressEvent.total) * 100).toFixed(2));
    },
  };
  $axios
    .post($common.fileUrl + param.upload, formdata, config)
    .then((res: any) => {
      if (res.status === 200) {
        handleAvatarSuccess(res.data);
      } else {
        handleAvatarError(res, data.file);
      }
    })
    .catch((err: any) => {
      handleAvatarError(err, data.file);
    });
};
/** 上传成功 */
const handleAvatarSuccess = (response: any) => {
  if (response.retMsg) {
    $MessageBox.alert({ txt: response.retMsg, }).then(() => { }).catch(() => { })
    return;
  }
  const pathToken = `${response.path}/${response.token}`;
  file.value = pathToken; // 存储path+token
  if(props.params) {
    downloadFile(pathToken);
  }
};
/** 上传失败 */
const handleAvatarError = (err: any, file: any) => {
  error.value = true; // 置为失败
  $MessageBox.alert({ txt: `${file.name}上传失败`, type: 'danger' }).then(() => { }).catch(() => { })
}
/** 对话框的操作按钮 */
const buttons = ref([
  {
    title: '取消',
    plain: true,
    click: () => {
      emits('cancel');
    }
  },
  {
    title: '确定',
    click: () => {
      if (file.value) {
        emits('ok', {
          file: file.value
        });
      } else {
        $MessageBox.alert({ txt: "请选择文件", type: 'warning' }).then(() => { }).catch(() => { })
      }
    }
  },
]);
onMounted(() => {
  emits('buttons-ready', buttons.value);
});


</script>
  
<style lang="scss" scoped>
.upload-file {
  text-align: center;
  line-height: 20px;
  min-width: 200px;

  :deep(.el-upload-dragger) {
    padding: 0;
    display: flex;
    height: 160px;
    align-items: center;
    justify-content: space-evenly;
  }

}

.upload_icon_title {
  font-size: 16px;
  color: var(--theme-primary);

  .icon_box {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  span {
    display: block;
    margin-left: 8px;
  }
}

.upload_in {
  color: var(--text-black-45);
  font-size: 14px;
}

.upload__text {
  color: var(--text-black-45);
  padding-top: 12px;
}

.error_span {
  color: var(--assist-red);
}

.reload_upload {
  color: var(--theme-primary);
}
.show_file {
  position: relative;
  .delete_icon {
    position: absolute;
    right: 0;
    top: 0;
    color: var(--text-black-45);
  }
}
</style>